package com.ymt.bpm.service.platform.log.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ymt.bpm.dao.MDao;
import com.ymt.bpm.engine.EngineConst;
import com.ymt.bpm.model.PSystemlog;
import com.ymt.bpm.service.platform.log.SysLogService;
import com.ymt.bpm.util.Const;
import com.ymt.bpm.util.DateUtil;
import com.ymt.bpm.util.DhxUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Created by Johnny on 2017/3/22.
 */
@Service
public class SysLogServiceImpl implements SysLogService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MDao mDao;

    private String mapper = "PSystemlogMapper";

    @Override
    @Transactional(EngineConst.TRANSACTION_MANAGER)
    public int addLog(PSystemlog log) {
        if (log.getLogid()==null || log.getLogid().length()==0) {
            log.setLogid("LOG-"+ UUID.randomUUID().toString());
        }
        return mDao.insert(mapper, "insert", log);
    }

    @Override
    public JSONObject get(String tenantId, String logid, String lang, int timezoneOffset) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("logid", logid);
        PSystemlog log = mDao.selectOne(mapper, "selectByPrimaryKey", paramMap);
        return DhxUtil.toFastJsonWithDate(log, lang, timezoneOffset);
    }

    @Override
    public int delLog(String tenantId, String logid) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("logid", logid);
        return mDao.delete(mapper, "deleteByPrimaryKey", paramMap);
    }

    @Override
    public int purge(String tenantId) {
        return mDao.delete(mapper, "deleteAll", tenantId);
    }

    @Override
    public JSONObject query(String tenantId, String category,
                           String search, String sort, String order,
                           int offset, int limit, String lang, int timezoneOffset) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("category", category);
        paramMap.put("search", search);
        paramMap.put("sort", sort);
        paramMap.put("order", order);
        PageHelper.offsetPage(offset, limit);
        List<PSystemlog> list = mDao.selectList(mapper, "query", paramMap);
        PageInfo pageInfo = new PageInfo(list);
        JSONObject rtn = new JSONObject();
        JSONArray rows = new JSONArray();
        if (list!=null && list.size()>0) {
            for (PSystemlog log : list) {
                JSONObject row = DhxUtil.toFastJsonWithDate(log, lang, timezoneOffset);
                row.put("_ITEM_NO", ++offset);
                rows.add(row);
            }
        }
        rtn.put("rows", rows);
        rtn.put("total", pageInfo.getTotal());
        return rtn;
    }

    public void expLog(String tenantId, String piId, String taskId, String code, String category, String userId, String userName, Exception e) {
        new LogThread(tenantId, piId, taskId, code, category, userId, userName, e).start();
    }

    class LogThread extends Thread {

        String tenantId;
        String piId;
        String taskId;
        String code;
        String category;
        String userId;
        String userName;
        Exception e;

        LogThread(String tenantId, String piId, String taskId, String code, String category, String userId, String userName, Exception e) {
            this.tenantId = tenantId;
            if (userId==null) {
                this.userId = EngineConst.DEFAULT_USR_ID;
            } else {
                this.userId = userId;
            }
            if (userName==null) {
                this.userName = EngineConst.DEFAULT_USR_NAME;
            } else {
                this.userName = userName;
            }
            this.piId = piId;
            this.taskId = taskId;
            this.code = code;
            this.category = category;
            this.e = e;
        }

        public void run() {
            try {
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                e.printStackTrace(pw);
                // 新建一个系统日志对象并赋值
                PSystemlog log = new PSystemlog();
                if (tenantId!=null && tenantId.length()>0 && StringUtils.isNumeric(tenantId)) {
                    log.setTenantId(Integer.parseInt(tenantId));
                }
                log.setLogid("SYSLOG-" + UUID.randomUUID());
                log.setOwner(userId);
                log.setOwnername(userName);
                log.setLogdate(DateUtil.getGMTDate());
                log.setCode(code);
                log.setCategory(category);
                log.setDescription(sw.toString());
                log.setTaskId(taskId);
                log.setPiid(piId);
                int i = addLog(log);
                if (logger.isDebugEnabled()) {
                    logger.debug("System exception logged:"+i);
                }
            } catch (Exception e1) {
                logger.error("System exception logging faild.");
                e1.printStackTrace();
            }
        }
    }
}
